package com.bf.hotpoint.service.impl;
import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;
import static org.springframework.data.mongodb.core.query.Update.update;

import java.io.IOException;
import java.util.List;
import java.util.UUID;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.GeoResult;
import org.springframework.data.geo.GeoResults;
import org.springframework.data.geo.Metrics;
import org.springframework.data.geo.Point;
import org.springframework.data.geo.Shape;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.index.GeospatialIndex;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import com.bf.hotpoint.common.BanWordsUtil;
import com.bf.hotpoint.domain.TestObject;
import com.bf.hotpoint.repository.mongo.TestRepository;

/**
 * Service for initializing MongoDB with sample data using {@link MongoTemplate}
 */

@Service
public class TestInitMongoService {
	
	@Autowired
	private MongoTemplate mongoTemplate;
	
	@Autowired
	private TestRepository testRep;

	//@PostConstruct
	public void init() {
		
		
		//init illegale key word
		BanWordsUtil.initBanWordsList();
		
		// Drop existing collections
		mongoTemplate.dropCollection("testObject");

		// Create new records
		TestObject testObject = new TestObject();
		testObject.setName("chengdu");
		testObject.setAge(22);
		//testObject.setLocation(new double[]{30.675241, 104.080662});
		testObject.setLocation(new Point(30.657550, 104.066421));
		testObject.setId(UUID.randomUUID().toString());
		
		TestObject testObject2 = new TestObject();
		testObject2.setName("wu min inlend");
		testObject2.setAge(42);
		//testObject2.setLocation(new double[]{1.412139, 103.957676});
		testObject2.setLocation(new Point(1.417907, 103.940395));
		testObject2.setId(UUID.randomUUID().toString());
		
		TestObject testObject3 = new TestObject();
		testObject3.setName("amk hub");
		testObject3.setAge(42);
		//testObject3.setLocation(new double[]{1.370034, 103.848103});
		testObject3.setLocation(new Point(1.369315, 103.847920));
		testObject3.setId(UUID.randomUUID().toString());

		TestObject testObject4 = new TestObject();
		testObject4.setName("hougang 1");
		testObject4.setAge(42);
		//testObject4.setLocation(new double[]{1.375991, 103.879715});
		testObject4.setLocation(new Point(1.375625, 103.879281));
		testObject4.setId(UUID.randomUUID().toString());
		
		TestObject testObject5 = new TestObject();
		testObject5.setName("ma lai xi ya");
		testObject5.setAge(42);
		//testObject5.setLocation(new double[]{4.278066, 101.933743});
		testObject5.setLocation(new Point(3.143822, 101.694369));
		testObject5.setId(UUID.randomUUID().toString());
		
		TestObject testObject6 = new TestObject();
		testObject6.setName("MOTO");
		testObject6.setAge(42);
		//testObject6.setLocation(new double[]{1.390308, 103.845765});
		testObject6.setLocation(new Point(1.389854, 103.845032));
		testObject6.setId(UUID.randomUUID().toString());
		
		TestObject testObject7 = new TestObject();
		testObject7.setName("APPLE");
		testObject7.setAge(42);
		//testObject7.setLocation(new double[]{1.389139, 103.845202});
		testObject7.setLocation(new Point(1.389854, 103.845032));
		testObject7.setId(UUID.randomUUID().toString());
		
		// Insert to db
		mongoTemplate.insert(testObject, "testObject");
		mongoTemplate.insert(testObject2, "testObject");
		mongoTemplate.insert(testObject3, "testObject");
		mongoTemplate.insert(testObject4, "testObject");
		mongoTemplate.insert(testObject5, "testObject");
		mongoTemplate.insert(testObject6, "testObject");
		mongoTemplate.insert(testObject7, "testObject");
		
		GeospatialIndex geospatialIndex = new GeospatialIndex("location");
		mongoTemplate.indexOps(TestObject.class).ensureIndex(geospatialIndex);
		
		for(TestObject to : mongoTemplate.findAll(TestObject.class))
		{
			System.out.println(to);
		}
		
		
		for(TestObject to : testRep.findByAge(22))
		{
			System.out.println(String.format("age:22 %s", to));
		}
		
		TestObject to = testRep.findByName("zb");
		System.out.println(String.format("name:zb %s", to));
		
		Page<TestObject> pageone = testRep.findAll(new PageRequest(0, 1));
		System.out.println(String.format("page1: %s", pageone.getContent().get(0)));
	}
	
	public void deleteOjb()
	{
		testRep.deleteByAge(22);
		for(TestObject to : testRep.findByAge(22))
		{
			System.out.println(String.format("delete age:22 %s", to));
		}
	}
	
	public void near(int dis)
	{
		Point point = new Point(1.389103, 103.843954);
		Distance distance = new Distance(dis, Metrics.KILOMETERS);
	
		GeoResults<TestObject> grs = testRep.findByLocationNear(point,distance);
		for(GeoResult<TestObject> gr : grs)
		{
			System.out.println(String.format("near:22 %s", gr.getContent()));
		}
	}
	
	public void in(double dis)
	{
		Point center = new Point(1.389103, 103.843954);
		Distance radius = new Distance(dis, Metrics.NEUTRAL);
		Shape circle = new Circle(center, radius);
		
		List<TestObject> grs = mongoTemplate.find(new Query(Criteria.where("location").within(circle)), TestObject.class);
		for(TestObject gr : grs)
		{
			System.out.println(String.format("near:22 %s", gr));
		}
		
		
		/*Point location = new Point(1.389711, 103.829892);
		NearQuery query = NearQuery.near(1.389711, 103.829892, Metrics.MILES).maxDistance(10);
		GeoResults<TestObject> grs = mongoTemplate.geoNear(query, TestObject.class);
		List<GeoResult<TestObject>> result =  grs.getContent();
		for(GeoResult<TestObject> gr : result)
		{
			System.out.println(String.format("near:22 %s", gr.getContent()));
		}*/
	}
	
	public void updateName(String oldName,String newName)
	{
		mongoTemplate.updateFirst(query(where("name").is(oldName)), update("name", newName), TestObject.class, "testObject");
		TestObject to = mongoTemplate.findOne(query(where("name").is(newName)), TestObject.class);
		System.out.println(to);
	}
}
